package com.lhy.mymall.exception;

import com.lhy.mymall.common.ApiRestResponse;
import com.sun.mail.util.MailConnectException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.ArrayList;
import java.util.List;


/**
 * @author: 卢辉宇
 * @date: 2022/12/13 14:55
 * @description: 拦截处理统一异常
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    /*通过LoggerFactory得到log来进行在控制台的打印显示*/
    static final Logger log =  LoggerFactory.getLogger(GlobalExceptionHandler.class);

    //捕获的是系统异常
    @ExceptionHandler(Exception.class)
    public ApiRestResponse handlerException(Exception e){
        log.error("Default Exception",e);
        return ApiRestResponse.error(ExceptionEnum.SYSTEM_ERROR);
    }

    /*在service层的异常向上抛出时，返回给前端的提示封装 成一致的json对象*/
    //捕获的自定义异常
    @ExceptionHandler(MallException.class)
    public ApiRestResponse handlerMallException(MallException e){
        log.error("MallException",e);
        return ApiRestResponse.error(e.getCODE(),e.getMSG());
    }


    /*在service层的异常向上抛出时，返回给前端的提示封装 成一致的json对象*/
    //捕获的自定义异常(方法参数无效异常)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ApiRestResponse handlerMethodArgumentNotValidException(MethodArgumentNotValidException e){
        log.error("MethodArgumentNotValidException",e);
        // 想返回ApiRestResponse.error(状态码,e.getMessage());但是getMessage包含的信息过多，需要进一步处理
        return handleBindingResult(e.getBindingResult());
    }

    /**
     * getMessage包含的信息过多,进一步处理方法
     * @param result
     * @return
     */
    private ApiRestResponse handleBindingResult(BindingResult result){
        //把异常处理为对外暴露的格式
        List<String> list=new ArrayList<>();
        //判断异常是否包含错误
        if (result.hasErrors()) {
            //拿到错误的列表
            List<ObjectError> allErrors = result.getAllErrors();
            //遍历错误信息列表，并把错误的信息放入前面创建的list集合中
            for (ObjectError error:allErrors) {
                list.add(error.getDefaultMessage());
            }
        }
        //返回ApiRestResponse.error(状态码,e.getMessage());
        return ApiRestResponse.error(9999,list.toString());
    }
}
